# Завантаження покетів та набору даних
library(tidyverse)
TMDB <- read_csv("U:/Master's_work_Boiko/Data_Analysis_movie/tmdb_movies.csv")
TMDB
# Кількість зміних і спостережень
dim(TMDB)
## [1] 10866 21
# Імена зміних
names(TMDB)
## [1] "id" "imdb_id" "popularity"
## [4] "budget" "revenue" "original_title"
## [7] "cast" "homepage" "director"
## [10] "tagline" "keywords" "overview"
## [13] "runtime" "genres" "production_companies"
## [16] "release_date" "vote_count" "vote_average"
## [19] "release_year" "budget_adj" "revenue_adj"
# Видалення нерелевантних даних
TMDB_cleaned <- TMDB %>% select(-c(id, imdb_id, popularity, budget_adj, revenue_adj, cast, homepage, director, tagline, keywords, overview, production_companies, release_date))
TMDB_cleaned
# Перевірка кількість NA значень у кожній змінній
na_count <- sapply(TMDB_cleaned, function(y) sum(length(which(is.na(y)))))
print(na_count)
## budget revenue original_title runtime genres
## 0 0 0 0 23
## vote_count vote_average release_year
## 0 0 0
# Видалення рядків, які містять NA значення
TMDB_cleaned <- na.omit(TMDB_cleaned)
print(sum(is.na(TMDB_cleaned)))
## [1] 0
# Перевірка кількість NA значень у кожній змінній
na_count <- sapply(TMDB_cleaned, function(y) sum(length(which(is.na(y)))))
# Перевірка результату
print(na_count)
## budget revenue original_title runtime genres
## 0 0 0 0 0
## vote_count vote_average release_year
## 0 0 0
# Кількість зміних і спостережень
dim(TMDB_cleaned)
## [1] 10843 8
# Перевірка на кількість 0 значень у кожній змінній
zero_count <- sapply(TMDB_cleaned, function(y) sum(y == 0, na.rm = TRUE))
print(zero_count)
## budget revenue original_title runtime genres
## 5674 5993 0 30 0
## vote_count vote_average release_year
## 0 0 0
# Видалення рядків, де budget, revenue та runtime дорівнює 0
TMDB_cleaned <- TMDB_cleaned %>%
filter(budget > 0 & revenue > 0 & runtime > 0)
# Встановлення параметра scipen
options(scipen=999)
# Визначення мінімального значення для змінних budget, revenue та runtime
min_data <- sapply(TMDB_cleaned[, c("runtime", "budget", "revenue")], min, na.rm = TRUE)
min_data
## runtime budget revenue
## 15 1 2
# Кількість зміних і спостережень
dim(TMDB_cleaned)
## [1] 3855 8
# Перевірка на наявність дублікатів
original_nrow <- nrow(TMDB_cleaned)
duplicated_rows <- TMDB_cleaned[duplicated(TMDB_cleaned),]
# Якщо є дублікати, вивести їх кількість
if(nrow(duplicated_rows) > 0) {
print(paste("Number of duplicated rows: ", nrow(duplicated_rows)))
}
## [1] "Number of duplicated rows: 1"
# Видалення дублікатів
TMDB_cleaned <- distinct(TMDB_cleaned)
# Перевірка результату
new_nrow <- nrow(TMDB_cleaned)
print(paste("Кількість рядків до видалення дублікатів: ", original_nrow))
## [1] "Кількість рядків до видалення дублікатів: 3855"
print(paste("Кількість рядків після видалення дублікатів: ", new_nrow))
## [1] "Кількість рядків після видалення дублікатів: 3854"
# Встановлення порогового значення
revenue_threshold <- 11000
budget_threshold <- 1000
# Відфільтровування фільмів з касовими зборами та бюджетом нижче порогового значення
TMDB_cleaned <- TMDB_cleaned %>%
filter(revenue > revenue_threshold & budget > budget_threshold)
# Перевірка результату
summary(TMDB_cleaned$budget )
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 7000 10000000 25000000 37609526 50000000 425000000
summary(TMDB_cleaned$revenue )
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 13308 14460000 46236000 109155433 126216940 2781505847
# Фільтрування фільмів з касовими зборами менше за 20000 тисяч
low_revenue_movies <- TMDB_cleaned %>%
filter(revenue < 20000)
# Виведення перших рядків цього списка для перевірки
low_revenue_movies
# Виведення структури DataFrame, що включає імена та типи змінних, а також перші кілька значень кожної змінної
str(TMDB_cleaned)
## tibble [3,801 × 8] (S3: tbl_df/tbl/data.frame)
## $ budget : num [1:3801] 150000000 150000000 110000000 200000000 190000000 135000000 155000000 108000000 74000000 175000000 ...
## $ revenue : num [1:3801] 1513528810 378436354 295238201 2068178225 1506249360 ...
## $ original_title: chr [1:3801] "Jurassic World" "Mad Max: Fury Road" "Insurgent" "Star Wars: The Force Awakens" ...
## $ runtime : num [1:3801] 124 120 119 136 137 156 125 141 91 94 ...
## $ genres : chr [1:3801] "Action|Adventure|Science Fiction|Thriller" "Action|Adventure|Science Fiction|Thriller" "Adventure|Science Fiction|Thriller" "Action|Adventure|Science Fiction|Fantasy" ...
## $ vote_count : num [1:3801] 5562 6185 2480 5292 2947 ...
## $ vote_average : num [1:3801] 6.5 7.1 6.3 7.5 7.3 7.2 5.8 7.6 6.5 8 ...
## $ release_year : num [1:3801] 2015 2015 2015 2015 2015 ...
## - attr(*, "na.action")= 'omit' Named int [1:23] 425 621 998 1713 1898 2371 2377 2854 3280 4548 ...
## ..- attr(*, "names")= chr [1:23] "425" "621" "998" "1713" ...
# Перевірка розміру DataFrame
print(paste("Кількість рядків: ", nrow(TMDB_cleaned)))
## [1] "Кількість рядків: 3801"
print(paste("Кількість стовбців: ", ncol(TMDB_cleaned)))
## [1] "Кількість стовбців: 8"
# Перевірка загальних статистичних характеристик змінних
summary(TMDB_cleaned)
## budget revenue original_title runtime
## Min. : 7000 Min. : 13308 Length:3801 Min. : 26.0
## 1st Qu.: 10000000 1st Qu.: 14460000 Class :character 1st Qu.: 96.0
## Median : 25000000 Median : 46236000 Mode :character Median :106.0
## Mean : 37609526 Mean : 109155433 Mean :109.4
## 3rd Qu.: 50000000 3rd Qu.: 126216940 3rd Qu.:119.0
## Max. :425000000 Max. :2781505847 Max. :338.0
## genres vote_count vote_average release_year
## Length:3801 Min. : 10.0 Min. :2.200 Min. :1960
## Class :character 1st Qu.: 73.0 1st Qu.:5.700 1st Qu.:1995
## Mode :character Median : 207.0 Median :6.200 Median :2004
## Mean : 533.8 Mean :6.174 Mean :2001
## 3rd Qu.: 584.0 3rd Qu.:6.700 3rd Qu.:2010
## Max. :9767.0 Max. :8.400 Max. :2015
# Перевірка перших та останніх рядків DataFrame
head(TMDB_cleaned)
tail(TMDB_cleaned)
# Розподіл рейтингу фільму (vote_average)
ggplot(TMDB_cleaned, aes(x=vote_average)) +
geom_histogram(binwidth=0.5, fill="blue", color="black", alpha=0.7) +
labs(title="Розподіл рейтингу фільмів", x="Рейтинг", y="Кількість фільмів")

library(patchwork)
## Warning: пакет 'patchwork' был собран под R версии 4.3.2
p1 <- ggplot(TMDB_cleaned, aes(x=budget)) +
geom_histogram(bins=30, fill="blue") +
theme_minimal() +
ggtitle("Бюджет")
p2 <- ggplot(TMDB_cleaned, aes(x=revenue)) +
geom_histogram(bins=30, fill="green") +
theme_minimal() +
ggtitle("Дохід")
p3 <- ggplot(TMDB_cleaned, aes(x=runtime)) +
geom_histogram(bins=30, fill="red") +
theme_minimal() +
ggtitle("Тривалість")
p4 <- ggplot(TMDB_cleaned, aes(x=vote_average)) +
geom_histogram(bins=30, fill="orange") +
theme_minimal() +
ggtitle("Середній Рейтинг")
p5 <- ggplot(TMDB_cleaned, aes(x=release_year)) +
geom_histogram(bins=30, fill="purple") +
theme_minimal() +
ggtitle("Рік Випуску")
p6 <- ggplot(TMDB_cleaned, aes(x=vote_count)) +
geom_histogram(bins=30, fill="yellow") +
theme_minimal() +
ggtitle("Кількість Голосів")
# Об'єднання графіків за допомогою patchwork
layout <- (p1 + p2) / (p3 + p4) / (p5 + p6)
layout

ggplot(TMDB_cleaned, aes(x=revenue)) +
geom_density(fill="blue", color="black", alpha=0.7) +
theme_minimal() +
labs(title="Розподіл касових зборів", x="Касові збори", y="Щільність")

# Розділяємо жанри на різні рядки
data_expanded <- TMDB_cleaned %>%
separate_rows(genres, sep = "\\|")
# Перетворення жанрів на бінарні змінні (dummy variables)
data_dummies <- data_expanded %>%
pivot_wider(names_from = genres, values_from = genres, values_fill = list(genres = "Absent")) %>%
mutate(across(-c(original_title, runtime, vote_count, vote_average, release_year, budget, revenue), ~ifelse(. == "Absent", 0, 1)))
# Перевірка перших та останніх рядків DataFrame
data_dummies <- data_dummies %>% rename(TV_Movie = `TV Movie`)
data_dummies <- data_dummies %>% rename(Science_Fiction = `Science Fiction`)
head(data_dummies)
# Описова статистика
summary(data_dummies)
## budget revenue original_title runtime
## Min. : 7000 Min. : 13308 Length:3801 Min. : 26.0
## 1st Qu.: 10000000 1st Qu.: 14460000 Class :character 1st Qu.: 96.0
## Median : 25000000 Median : 46236000 Mode :character Median :106.0
## Mean : 37609526 Mean : 109155433 Mean :109.4
## 3rd Qu.: 50000000 3rd Qu.: 126216940 3rd Qu.:119.0
## Max. :425000000 Max. :2781505847 Max. :338.0
## vote_count vote_average release_year Action
## Min. : 10.0 Min. :2.200 Min. :1960 Min. :0.000
## 1st Qu.: 73.0 1st Qu.:5.700 1st Qu.:1995 1st Qu.:0.000
## Median : 207.0 Median :6.200 Median :2004 Median :0.000
## Mean : 533.8 Mean :6.174 Mean :2001 Mean :0.282
## 3rd Qu.: 584.0 3rd Qu.:6.700 3rd Qu.:2010 3rd Qu.:1.000
## Max. :9767.0 Max. :8.400 Max. :2015 Max. :1.000
## Adventure Science_Fiction Thriller Fantasy
## Min. :0.0000 Min. :0.0000 Min. :0.000 Min. :0.0000
## 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.000 1st Qu.:0.0000
## Median :0.0000 Median :0.0000 Median :0.000 Median :0.0000
## Mean :0.1949 Mean :0.1355 Mean :0.312 Mean :0.1023
## 3rd Qu.:0.0000 3rd Qu.:0.0000 3rd Qu.:1.000 3rd Qu.:0.0000
## Max. :1.0000 Max. :1.0000 Max. :1.000 Max. :1.0000
## Crime Western Drama Family
## Min. :0.00 Min. :0.00000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.00 1st Qu.:0.00000 1st Qu.:0.0000 1st Qu.:0.0000
## Median :0.00 Median :0.00000 Median :0.0000 Median :0.0000
## Mean :0.17 Mean :0.01342 Mean :0.4567 Mean :0.1102
## 3rd Qu.:0.00 3rd Qu.:0.00000 3rd Qu.:1.0000 3rd Qu.:0.0000
## Max. :1.00 Max. :1.00000 Max. :1.0000 Max. :1.0000
## Animation Comedy Mystery Romance
## Min. :0.00000 Min. :0.0000 Min. :0.00000 Min. :0.0000
## 1st Qu.:0.00000 1st Qu.:0.0000 1st Qu.:0.00000 1st Qu.:0.0000
## Median :0.00000 Median :0.0000 Median :0.00000 Median :0.0000
## Mean :0.05235 Mean :0.3517 Mean :0.08971 Mean :0.1721
## 3rd Qu.:0.00000 3rd Qu.:1.0000 3rd Qu.:0.00000 3rd Qu.:0.0000
## Max. :1.00000 Max. :1.0000 Max. :1.00000 Max. :1.0000
## War History Music Horror
## Min. :0.00000 Min. :0.00000 Min. :0.00000 Min. :0.0000
## 1st Qu.:0.00000 1st Qu.:0.00000 1st Qu.:0.00000 1st Qu.:0.0000
## Median :0.00000 Median :0.00000 Median :0.00000 Median :0.0000
## Mean :0.03131 Mean :0.03368 Mean :0.03499 Mean :0.1194
## 3rd Qu.:0.00000 3rd Qu.:0.00000 3rd Qu.:0.00000 3rd Qu.:0.0000
## Max. :1.00000 Max. :1.00000 Max. :1.00000 Max. :1.0000
## Documentary Foreign TV_Movie
## Min. :0.000000 Min. :0.00000 Min. :0.0000000
## 1st Qu.:0.000000 1st Qu.:0.00000 1st Qu.:0.0000000
## Median :0.000000 Median :0.00000 Median :0.0000000
## Mean :0.008945 Mean :0.00342 Mean :0.0002631
## 3rd Qu.:0.000000 3rd Qu.:0.00000 3rd Qu.:0.0000000
## Max. :1.000000 Max. :1.00000 Max. :1.0000000
#завантаження пакету ggcorrplot
library(ggcorrplot)
## Warning: пакет 'ggcorrplot' был собран под R версии 4.3.2
# Кореляційний аналіз
data_numbers <- TMDB_cleaned %>% select(-c(original_title, genres))
correlation_matrix <- cor(data_numbers)
# Візуалізація кореляційної матриці
ggcorrplot(correlation_matrix, lab = TRUE,title ='Correlation Matrix of Movie Variables', lab_size = 3)

# Кореляційний аналіз
data_num <- data_dummies %>% select(-c(original_title, runtime, vote_count, release_year, budget, Adventure, Thriller, Fantasy, Crime, Western, Family, Comedy, Mystery, Romance, Music, Foreign, TV_Movie))
correlation_mat <- cor(data_num)
# Візуалізація кореляційної матриці
ggcorrplot(correlation_mat, lab = TRUE,title ='Correlation Matrix of Movie Variables', lab_size = 3)

# Побудова графіку Бюджет vs Доходи
ggplot(TMDB_cleaned, aes(x = budget, y = revenue)) +
geom_point(aes(color = vote_average), alpha = 0.6) + # Додавання кольору залежно від рейтингу
geom_smooth(method = "lm", se = FALSE, color = "blue") + # Лінія регресії
scale_x_continuous(labels = scales::comma) + # Форматування осі X
scale_y_continuous(labels = scales::comma) + # Форматування осі Y
labs(title = "Бюджет vs Касові збори", x = "Бюджет (у доларах)", y = "Касові збори (у доларах)") +
theme_minimal() + # Застосування теми
theme(legend.position = "bottom") # Розміщення легенди
## `geom_smooth()` using formula = 'y ~ x'

# Побудова графіку Кількість голосів vs Доходи
ggplot(TMDB_cleaned, aes(x = vote_count, y = revenue)) +
geom_point(alpha = 0.5) + # використання прозорості для кращого візуального представлення
geom_smooth(method = "lm", se = FALSE, color = "blue") + # Лінія регресії
scale_x_continuous(labels = scales::comma) + # Форматування осі X
scale_y_continuous(labels = scales::comma) + # Форматування осі Y
theme_minimal() + # Застосування теми
labs(title = "Кількість голосів vs Касові збори", x = "Кількість голосів", y = "Касові збори")
## `geom_smooth()` using formula = 'y ~ x'

# Створення графіка
ggplot(TMDB_cleaned, aes(x = vote_count, y = vote_average)) +
geom_point(alpha = 0.5) + # використання прозорості для кращого відображення даних
geom_smooth(method = "lm", se = FALSE, color = "blue") + # Лінія регресії
theme_minimal() +
labs(title = "Кількість Голосів vs Рейтинг",
x = "Кількість Голосів",
y = "Рейтинг")
## `geom_smooth()` using formula = 'y ~ x'

genres_data <- data_dummies %>%
gather(key=genre, value=value, -original_title, -runtime, -vote_count, -vote_average, -release_year, -budget, -revenue, -Foreign, -TV_Movie) %>%
filter(value == 1)
genre_rating <- genres_data %>%
group_by(genre) %>%
summarise(avg_rating = mean(vote_average))
ggplot(genre_rating, aes(x=genre, y=avg_rating)) +
geom_bar(stat="identity", fill="purple") +
coord_flip() +
labs(title="Середній рейтинг за жанром", x="Жанр", y="Середній рейтинг")

genres_data <- data_dummies %>%
gather(key=genre, value=value, -original_title, -runtime, -vote_count, -vote_average, -release_year, -budget, -revenue, -Foreign, -TV_Movie) %>%
filter(value == 1)
genre_rating <- genres_data %>%
group_by(genre) %>%
summarise(avg_revenue = mean(revenue))
ggplot(genre_rating, aes(x=genre, y=avg_revenue)) +
geom_bar(stat="identity", fill="purple") +
coord_flip() +
labs(title="Середній дохід за жанром", x="Жанр", y="Середній дохід")

# Підготовка даних: зміна структури даних з широкої на довгу
long_data <- data_dummies %>%
pivot_longer(
cols = c(Action, Animation, Science_Fiction, Adventure, Comedy, Documentary, Drama, Thriller, Fantasy, History, Horror, Crime, Western, War, Family, Mystery, Romance, Music), # Замініть на назви ваших жанрових колонок
names_to = "Genre",
values_to = "Genre_Present"
) %>%
filter(Genre_Present == 1)
# Розрахунок середнього чистого доходу за жанрами
average_net_revenue_by_genre <- long_data %>%
group_by(Genre) %>%
summarize(
Average_Net_Revenue = mean(revenue - budget, na.rm = TRUE)
)
# Візуалізація
ggplot(average_net_revenue_by_genre, aes(x = Genre, y = Average_Net_Revenue)) +
geom_bar(stat = "identity", fill = "steelblue") +
theme_minimal() +
coord_flip() + # Для горизонтального бар-графіка
labs(title = "Середній чистий дохід фільмів за жанрами",
x = "Жанр",
y = "Середній чистий дохід")

genre_count <- genres_data %>%
group_by(genre) %>%
count()
ggplot(genre_count, aes(x=genre, y=n)) +
geom_bar(stat="identity", fill="cyan") +
coord_flip() +
labs(title="Кількість фільмів за жанром", x="Жанр", y="Кількість фільмів")
